#include <stdio.h>
#include <stdlib.h>
#include "wt.h"

ReadURB::ReadURB(WT *window, int maxurb, QObject *parent): QThread(parent)
{
	this->window = window;
	this->maxurb = maxurb;
	this->tpgenthread = 0;

	connect(this, SIGNAL(setstate(int)), this->window, SLOT(setstate(int)), Qt::DirectConnection);
	connect(this, SIGNAL(getstate()), this->window, SLOT(getstate()), Qt::DirectConnection);
	connect(this, SIGNAL(setmemory(const unsigned char *,int)), this->window, SLOT(setmemory(const unsigned char *,int)), Qt::DirectConnection);
	connect(this, SIGNAL(getmemory(unsigned char *)), this->window, SLOT(getmemory(unsigned char *)), Qt::DirectConnection);
	connect(this, SIGNAL(initialize()), this->window, SLOT(initialize()), Qt::DirectConnection);
	connect(this, SIGNAL(setperiod(int)), this->window, SLOT(setperiod(int)), Qt::DirectConnection);
	connect(this, SIGNAL(getperiod()), this->window, SLOT(getperiod()), Qt::DirectConnection);
	connect(this, SIGNAL(setledcolor(int)), this->window, SLOT(setledcolor(int)), Qt::DirectConnection);
	connect(this, SIGNAL(getledcolor()), this->window, SLOT(getledcolor()), Qt::DirectConnection);
	connect(this, SIGNAL(getserial(char *)), this->window, SLOT(getserial(char *)), Qt::DirectConnection);
	connect(this, SIGNAL(showurb(char *)), this->window, SLOT(showurb(char *)), Qt::DirectConnection);
}

void ReadURB::run()
{
	char buffer[8];
	FILE *f;
	static int x;

	if(!(f = fopen("/proc/temprobe","r+"))) {
		perror("/proc/temprobe");
		exit(1);
	}

	this->tpgenthread = new TPGen(this->window);
	this->tpgenthread->start();
	
	while( x++ < this->maxurb || this->maxurb==0 ){
		int ret;
		if((ret = fread(buffer, 8, 1, f))!=1) {
			perror("fread");
			break;
		}
		this->copewith(buffer, f);
		fflush(f); // clean buffer
		fseek(f,0,SEEK_SET);
	}
	
	this->tpgenthread->live = 0;
	this->tpgenthread->wait();
	QApplication::exit(1);
}

void ReadURB::copewith(char buf[8], FILE *f)
{
	char cmd = buf[0];
	char *param = buf+1;
	char localbuffer[8]={0};
	
	emit this->showurb(buf);

	localbuffer[0]=cmd;
	switch(cmd)
	  {
		case 0x10: /* Get Status */
			localbuffer[2] = emit getstate()==WT::START? 1 : 0;
			goto send;
		case 0x11: case 0x12: case 0x13: /* Write local none violate memory */
		case 0x14: case 0x15: case 0x16: 
			emit setmemory((const unsigned char *)param, cmd-0x10);
			return;
		case 0x17: /* Read local none violate memory */
			this->window->getmemory((unsigned char *)localbuffer+2);
			goto send;
		case 0x18: /* Start measurement */
			if(strncmp(param, "\0\0\0\0\0\0\0", 7)==0)
			  {
				emit setstate(WT::START);
				if(this->tpgenthread)
					this->tpgenthread->adjustT = 1;
			  }
			return;
		case 0x19: /* Stop measurement */
			if(strncmp(param, "\0\0\0\0\0\0\0", 7)==0)
			  {
				if(this->tpgenthread)
					this->tpgenthread->adjustT = 0;
				emit setstate(WT::STOP);
			  }
			return;
		case 0x1A: /* Initialize device */
			if(strncmp(param, "\0\0\0\0\0\0\0", 7)==0)
				emit initialize();
			return;
		case 0x1B: /* Set measurement period */
			emit setperiod((unsigned char)param[0]*256+(unsigned char)param[1]);
			return;
		case 0x1C: /* Get measurement period */
			  {
				int period = this->window->getperiod();
				localbuffer[2] = period>>8;
				localbuffer[3] = period&0xFF;
			  }
			goto send;
		case 0x1D: /* Set LED state */
			if(strncmp(param, "\x80\x10\0\0\0\0\0", 7)==0)
				emit setledcolor(WT::GREEN);
			else if(strncmp(param, "\0\4\0\0\0\0\0", 7)==0)
				emit setledcolor(WT::YELLOW);
			else if(strncmp(param, "\x80\0\0\0\0\0\0", 7)==0)
				emit setledcolor(WT::OFF);
			return;
		case 0x1E: /* Get LED state */
			localbuffer[2]= this->window->getledcolor()==WT::GREEN ? 0x10 :
				( this->window->getledcolor()==WT::YELLOW ? 4 : 0 );
			goto send;
		case 0x20: /* Get serial number */
			this->window->getserial(localbuffer+2);
			goto send;
	  }
	return;
send:
	localbuffer[1]= ::nextcountervalue();
	fseek(f, 0, 0);
	fwrite(localbuffer, 8, 1, f);
}
